﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Text.RegularExpressions;

namespace ParseXAML
{

    /// <summary>
    /// To use with <c ref="NamespaceAssociations" />
    /// </summary>
    internal class NamespaceAssociation
    {
        internal string NamespaceName;

        /// <summary>
        /// Nom de l'assembly ou Uri correspondante
        /// </summary>
        internal string AssemblyName;

        internal bool IsUri;

        internal NamespaceAssociation(string NamespaceName, string AssemblyName, bool IsUri)
        {
            this.NamespaceName = NamespaceName;
            this.AssemblyName = AssemblyName;
            this.IsUri = IsUri;
        }
    }

    /// <summary>
    /// Contains the associations between the alias xmlns and namespace&assembly
    /// </summary>
    internal class NamespaceAssociations : Dictionary<string, NamespaceAssociation>
    {
        internal const string nsXamlName = "http://schemas.microsoft.com/winfx/2006/xaml";
        internal const string nsXamlNamePresentation = "http://schemas.microsoft.com/winfx/2006/xaml/presentation";

        /// <summary>
        /// Etract the information from the header
        /// </summary>
        /// <param name="rootElement">The root element</param>
        internal NamespaceAssociations(XmlElement rootElement)
        {
            foreach ( var v in rootElement.Attributes )
            {
                XmlAttribute v2 = (XmlAttribute)v;
                if (v2.Name.StartsWith("xmlns"))
                {
                    string tagName;

                    // Namespace by default
                    if ( v2.Name == "xmlns" )
                        tagName = "";
                    else
                        tagName = v2.Name.Substring(("xmlns:").Length);
                    string value = v2.InnerXml;
                    Match mc = Regex.Match(value, @"clr\-namespace:([^\;]*)\;assembly\=([^\;]*)");
                    if (mc.Success)
                        this.Add(tagName, new NamespaceAssociation(mc.Groups[1].ToString(), mc.Groups[2].ToString(), false));
                    else
                    {
                        mc = Regex.Match(value, @"clr\-namespace:([^\;]*)");
                        if (mc.Success)
                            this.Add(tagName, new NamespaceAssociation(mc.Groups[1].ToString(), "", false));
                        else
                        {
                            if ((string.Compare(nsXamlName, value, StringComparison.OrdinalIgnoreCase) == 0) ||
                                (string.Compare(nsXamlNamePresentation, value, StringComparison.OrdinalIgnoreCase) == 0))
                                this.Add(tagName, new NamespaceAssociation("System.Windows.Controls", value, true));
                            else
                                this.Add(tagName, new NamespaceAssociation(string.Empty, value, true));
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Returns informations from the alias
        /// </summary>
        /// <param name="alias"></param>
        /// <returns></returns>
        internal NamespaceAssociation GetNamespaceAssociation(string alias)
        {
            NamespaceAssociation v;
            if (TryGetValue(alias, out v))
                return v;
            return null;
        }
    }
}
